package com.kernelstudio.framework.boot.autoconfigure.framework.compatible;
/*
 * This file is part of the kernelstudio package.
 *
 * (c) 2014-2024 zlin <admin@kernelstudio.com>
 *
 * For the full copyright and license information, please view the LICENSE file
 * that was distributed with this source code.
 */

import com.kernelstudio.framework.boot.condition.ConditionalClassNames;
import com.kernelstudio.framework.boot.condition.framework.compatible.ConditionalOnFlowableCompatible;
import com.kernelstudio.framework.boot.properties.framework.compatible.FrameworkDatabaseCompatibleProperties;
import org.flowable.app.engine.AppEngineConfiguration;
import org.flowable.app.spring.SpringAppEngineConfiguration;
import org.flowable.common.engine.impl.AbstractEngineConfiguration;
import org.flowable.spring.SpringProcessEngineConfiguration;
import org.flowable.spring.boot.EngineConfigurationConfigurer;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;

@Configuration
@ConditionalOnFlowableCompatible
public class FrameworkCompatibleFlowableAutoConfiguration {

    protected static void configureCompatible(AbstractEngineConfiguration configuration,
                                              FrameworkDatabaseCompatibleProperties properties) {
        switch (properties.getMode()) {
            case MYSQL:
                configuration.setDatabaseType(SpringProcessEngineConfiguration.DATABASE_TYPE_MYSQL);
                break;
            case ORACLE:
                configuration.setDatabaseType(SpringProcessEngineConfiguration.DATABASE_TYPE_ORACLE);
                break;
            case POSTGRES:
                configuration.setDatabaseType(SpringProcessEngineConfiguration.DATABASE_TYPE_POSTGRES);
                break;
            default:
                throw new RuntimeException("Unknown database mode " + properties.getMode());
        }
    }

    @Configuration
    @ConditionalOnFlowableCompatible
    @ConditionalOnClass(name = ConditionalClassNames.FLOWABLE_SPRING_APP_ENGINE)
    @EnableConfigurationProperties({
            FrameworkDatabaseCompatibleProperties.class
    })
    public static class FlowableDatabaseCompatibleSpringAppEngineAutoConfiguration
            implements EngineConfigurationConfigurer<SpringAppEngineConfiguration> {

        private final FrameworkDatabaseCompatibleProperties databaseCompatibleProperties;

        public FlowableDatabaseCompatibleSpringAppEngineAutoConfiguration(
                FrameworkDatabaseCompatibleProperties databaseCompatibleProperties) {
            this.databaseCompatibleProperties = databaseCompatibleProperties;
        }

        @Override
        public void configure(SpringAppEngineConfiguration engineConfiguration) {
            configureCompatible(engineConfiguration, databaseCompatibleProperties);
        }
    }

    @Configuration
    @ConditionalOnFlowableCompatible
    @ConditionalOnClass(name = ConditionalClassNames.FLOWABLE_SPRING_PROCESS_ENGINE)
    @EnableConfigurationProperties({
            FrameworkDatabaseCompatibleProperties.class
    })

    public static class FlowableDatabaseCompatibleProcessEngineAutoConfiguration
            implements EngineConfigurationConfigurer<SpringProcessEngineConfiguration> {

        private final FrameworkDatabaseCompatibleProperties databaseCompatibleProperties;

        public FlowableDatabaseCompatibleProcessEngineAutoConfiguration(
                FrameworkDatabaseCompatibleProperties databaseCompatibleProperties) {
            this.databaseCompatibleProperties = databaseCompatibleProperties;
        }

        @Override
        public void configure(SpringProcessEngineConfiguration engineConfiguration) {
            configureCompatible(engineConfiguration, databaseCompatibleProperties);
        }
    }

    @Configuration
    @ConditionalOnFlowableCompatible
    @ConditionalOnClass(name = ConditionalClassNames.FLOWABLE_APP_ENGINE)
    @EnableConfigurationProperties({
            FrameworkDatabaseCompatibleProperties.class
    })
    public static class FlowableDatabaseCompatibleAppEngineAutoConfiguration implements
            EngineConfigurationConfigurer<AppEngineConfiguration> {

        private final FrameworkDatabaseCompatibleProperties databaseCompatibleProperties;

        public FlowableDatabaseCompatibleAppEngineAutoConfiguration(
                FrameworkDatabaseCompatibleProperties databaseCompatibleProperties) {
            this.databaseCompatibleProperties = databaseCompatibleProperties;
        }

        @Override
        public void configure(AppEngineConfiguration engineConfiguration) {
            configureCompatible(engineConfiguration, databaseCompatibleProperties);
        }
    }
}
